package com.guang.springbootselfmvc.restful;

import com.guang.springbootselfmvc.exception.ServiceException;
import com.guang.springbootselfmvc.exception.ServiceExceptions;
import com.guang.springbootselfmvc.utils.StringUtil;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;

@Data
public final class IgwHttpEntity<T> {
    private static final Logger logger = LoggerFactory.getLogger(IgwHttpEntity.class);
    private Integer code;
    private String msg;
    private Boolean success;
    private String serialNo;
    private IgwData<T> data;

    public IgwPage pageForRequest() throws ServiceException {
        this.validateData();
        this.validatePage();
        return this.data.getPage();
    }

    public T bodyForRequest() throws ServiceException {
        this.validateData();
        this.validateBody();
        return this.data.getBody();
    }

    public IgwPage pageForResponse(String errMsg) throws ServiceException {
        errMsg = StringUtil.isBlank(errMsg) ? "未知异常" : errMsg;
        this.validateHeader(errMsg);
        this.validateData();
        this.validatePage();
        return this.data.getPage();
    }

    public T bodyForResponse(String errMsg) throws ServiceException {
        errMsg = StringUtil.isBlank(errMsg) ? "未知异常" : errMsg;
        this.validateHeader(errMsg);
        this.validateData();
        this.validateBody();
        return this.data.getBody();
    }

    private void validateHeader(String errMsg) throws ServiceException {
        if (this.code == null || !ServiceExceptions.SSSS.getErrCode().equals(this.code)) {
            errMsg = StringUtil.isBlank(this.msg) ? errMsg : this.msg;
            logger.error(errMsg);
            ServiceExceptions serviceExceptions = ServiceExceptions.findServiceExceptions(this.code);
            throw serviceExceptions == null ? ServiceExceptions.F999.buildServiceException(errMsg) : serviceExceptions.buildServiceException(errMsg);
        }
    }

    private void validateData() throws ServiceException {
        if (this.data == null) {
            throw ServiceExceptions.F999.buildServiceException("报文data为空");
        }
    }

    private void validatePage() throws ServiceException {
        if (this.data == null || this.data.getPage() == null) {
            throw ServiceExceptions.F999.buildServiceException("报文data.page为空");
        }
    }

    private void validateBody() throws ServiceException {
        if (this.data == null || this.data.getBody() == null) {
            throw ServiceExceptions.F999.buildServiceException("报文data.body为空");
        }
    }

    public static <T> IgwHttpEntity<T> buildRequest(T body) {
        IgwHttpEntity<T> request = new IgwHttpEntity();
        IgwData data = new IgwData();
        data.setBody(body);
        request.setData(data);
        return request;
    }

    public static <T> IgwHttpEntity<T> buildRequest(String serialNo, T body) {
        IgwHttpEntity<T> request = new IgwHttpEntity();
        request.setSerialNo(serialNo);
        IgwData data = new IgwData();
        data.setBody(body);
        request.setData(data);
        return request;
    }

    public static <T> IgwHttpEntity<T> buildSuccessResponse() {
        IgwHttpEntity<T> response = new IgwHttpEntity();
        response.setCode(ServiceExceptions.SSSS.getErrCode());
        response.setMsg(ServiceExceptions.SSSS.getErrMsg());
        return response;
    }

    public static <T> IgwHttpEntity<T> buildSuccessResponse(T body) {
        IgwHttpEntity<T> response = new IgwHttpEntity();
        response.setCode(ServiceExceptions.SSSS.getErrCode());
        response.setMsg(ServiceExceptions.SSSS.getErrMsg());
        IgwData<T> igwData = new IgwData();
        igwData.setBody(body);
        response.setData(igwData);
        return response;
    }

    public static <T> IgwHttpEntity<Map<String, T>> buildSuccessResponse(Map<String, T> body) {
        IgwHttpEntity<Map<String, T>> response = new IgwHttpEntity();
        response.setCode(ServiceExceptions.SSSS.getErrCode());
        response.setMsg(ServiceExceptions.SSSS.getErrMsg());
        IgwData<Map<String, T>> igwData = new IgwData();
        igwData.setBody(body);
        response.setData(igwData);
        return response;
    }

    public static <T> IgwHttpEntity<List<T>> buildSuccessResponse(List<T> body) {
        IgwHttpEntity<List<T>> response = new IgwHttpEntity();
        response.setCode(ServiceExceptions.SSSS.getErrCode());
        response.setMsg(ServiceExceptions.SSSS.getErrMsg());
        IgwData<List<T>> igwData = new IgwData();
        igwData.setBody(body);
        response.setData(igwData);
        return response;
    }

    public static <T> IgwHttpEntity<List<T>> buildSuccessResponse(IgwPage page, List<T> body) {
        IgwHttpEntity<List<T>> response = new IgwHttpEntity();
        response.setCode(ServiceExceptions.SSSS.getErrCode());
        response.setMsg(ServiceExceptions.SSSS.getErrMsg());
        IgwData<List<T>> igwData = new IgwData();
        igwData.setPage(page);
        igwData.setBody(body);
        response.setData(igwData);
        return response;
    }

    public static <T> IgwHttpEntity<T> buildFailResponse(ServiceException serviceException) {
        IgwHttpEntity<T> response = new IgwHttpEntity();
        response.setCode(serviceException.getErrCode());
        response.setMsg(serviceException.getErrMsg());
        return response;
    }

    public IgwHttpEntity() {
        this.success = Boolean.TRUE;
    }

}